package com.novel.config;

import org.redisson.Redisson;
import org.redisson.RedissonAtomicLong;
import org.redisson.api.*;
import org.redisson.client.codec.StringCodec;
import org.redisson.client.protocol.ScoredEntry;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

/**
 * redisson操作类
 *
 * @author huawei
 */
@Service
public class RedissonHelper {

    @Resource
    private Redisson redissonClient;

    //hash add
    public void hadd(String key, String hk, Object value) {
        redissonClient.getMap(key).put(hk, value);
    }

    public Set<Map.Entry<Object, Object>> hashGetAll(String key) {
        return redissonClient.getMap(key).readAllEntrySet();
    }


    //检查hashkey是否存在
    public boolean checkHKey(String key, String f) {
        return redissonClient.getMap(key).containsKey(f);
    }

    public Object hash(String key, String hk) {
        return redissonClient.getMap(key).get(hk);
    }

    //建议生产不要调用
    public boolean checkKey(String key) {
        return redissonClient.getKeys().countExists(key) > 0;
    }

    //获取value根据key
    public Object getValue(String key) {
        return redissonClient.getBucket(key).get();
    }

    //批量获取value
    public Map<String, Object> getValueBatch(List<String> keys){
         return redissonClient.getBuckets().get(keys.toArray(new String[0]));
    }

    //批量存value
    public void setValueBatch(Map<String, Object> map){
        redissonClient.getBuckets(new StringCodec("utf-8")).set(map);
    }

    //获取value根据key
    public long getValueAto(String key) {
        return redissonClient.getAtomicLong(key).get();

    }

    //获取value根据key
    public boolean existValueAto(String key) {
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        return atomicLong.isExists();
    }

    //获取value根据key
    public void clearBucketAto(String key) {
        redissonClient.getAtomicLong(key).delete();
    }

    //设置key-value
    public void setValue(String key, Object value) {
        redissonClient.getBucket(key).set(value);
    }

    //设置key过期时间单位秒
    public void setValueAndSeconds(String key, Object value, long time) {
        redissonClient.getBucket(key).set(value, time, TimeUnit.SECONDS);
    }

    //设置key过期时间，自定义单位
    public void setValueAndTimeUnit(String key, Object value, long time, TimeUnit timeUnit) {
        redissonClient.getBucket(key).set(value, time, timeUnit);
    }

    //检查是否存在该值
    public boolean checkSet(String key, int id) {
        return redissonClient.getSet(key).contains(id);
    }

    //清除key
    public void clearBucket(String key) {
        redissonClient.getBucket(key).delete();
    }

    //删除key前缀
    public void scanClear(String keyPrefix) {
        redissonClient.getKeys().deleteByPattern(keyPrefix + "*");
    }

    public Iterable<String> scanGet(String keyPrefix) {
        return redissonClient.getKeys().getKeysByPattern(keyPrefix + "*");
    }

    public Stream<String> scanGetStream(String keyPrefix) {
        return redissonClient.getKeys().getKeysStreamByPattern(keyPrefix + "*");
    }

    public void clearMap(String key) {
        redissonClient.getMap(key).delete();
    }

    //加锁
    public void lock(String key) {
        redissonClient.getLock(key).lock();
    }

    //释放锁
    public void unlock(String key) {
        redissonClient.getLock(key).unlock();
    }

    //list添加
    public void listAddStr(String keyName, String value) {
        RList<String> list = redissonClient.getList(keyName, new StringCodec("utf-8"));
        list.add(value);
    }

    //list添加
    public void listAddAllStr(String keyName, List<String> value) {
        RList<String> list = redissonClient.getList(keyName, new StringCodec("utf-8"));
        list.addAll(value);
    }

    //list添加
    public void listAddAllLong(String keyName, List<Long> value) {
        RList<Long> list = redissonClient.getList(keyName, new StringCodec("utf-8"));
        list.addAll(value);
    }

    //list添加
    public void listClear(String keyName) {
        RList<Long> list = redissonClient.getList(keyName, new StringCodec("utf-8"));
        list.clear();
    }

    //添加obj到list
    public void addObj(String keyName, Object obj) {
        RList<Object> list = redissonClient.getList("list");
        list.add(obj);
    }

    //获取阻塞队列
    public RBlockingQueue<Object> blockQueue(String queueName) {
        return redissonClient.getBlockingQueue(queueName);
    }


    //获取到list object
    public List<Object> listObj(String keyName, Integer start, Integer end) {
        return redissonClient.getList(keyName, new StringCodec("utf-8")).range(start, end);
    }

    //获取到list string
    public RList<String> listString(String keyName) {
        return redissonClient.getList(keyName, new StringCodec("utf-8"));
    }

    //执行lua脚本
    public Object evalScript(String luaPath, List<Object> keys) {
        RScript script = redissonClient.getScript();
        return script.eval(RScript.Mode.READ_WRITE, luaPath, RScript.ReturnType.VALUE, keys);
    }

    //执行lua脚本
    public Object evalScriptParam(String luaPath, List<Object> keys, String... param) {
        RScript script = redissonClient.getScript();
        return script.eval(RScript.Mode.READ_WRITE, luaPath, RScript.ReturnType.VALUE, keys, param);
    }

    /**
     * 添加自增序号
     */
    public void setIncrement(String key, int value, long time, TimeUnit unit) {
        RedissonAtomicLong redissonAtomicLong = new RedissonAtomicLong(redissonClient.getCommandExecutor(), key);
        redissonAtomicLong.set(value);
        redissonAtomicLong.expire(time, unit);
    }

    /**
     * 获得自增序号
     */
    public long getIncrement(String key) {
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        return atomicLong.incrementAndGet();
    }

    /**
     * 原子减一
     */
    public long getDecrement(String key,Long days) {
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        atomicLong.expire(days, TimeUnit.DAYS);
        return atomicLong.decrementAndGet();
    }

    /**
     * 获得自增序号
     */
    public long getIncrement(String key, Long days) {
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        atomicLong.expire(days, TimeUnit.DAYS);
        return atomicLong.incrementAndGet();
    }


    /**
     * 原子+value
     * <p>
     * 返回更新后的值
     */
    public Long addAndGet(String key, Integer value, Long days) {
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        atomicLong.expire(days, TimeUnit.DAYS);
        return atomicLong.addAndGet(value);
    }

    /**
     * 原子+value
     * 返回更新后的值
     */
    public Long addAndGet(String key, Long value, Long days) {
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        atomicLong.expire(days, TimeUnit.DAYS);
        return atomicLong.addAndGet(value);
    }

    /**
     * 原子-1
     * 返回更新后的值
     */
    public Long decrementAndGet(String key) {
        RAtomicLong atomicLong = redissonClient.getAtomicLong(key);
        atomicLong.expire(7, TimeUnit.DAYS);
        return atomicLong.decrementAndGet();
    }

    /**
     * hash自增1
     */
    public Object hashIncrement(String key, Long hk) {
        return redissonClient.getMap(key).addAndGet(hk, 1);
    }

    /**
     * hash自增1
     */
    public Object hashIncrement(String key, String hk) {
        return redissonClient.getMap(key).addAndGet(hk, 1);
    }

    /**
     * hash自增number
     */
    public Object hashIncrement(String key, String hk, Long number) {
        return redissonClient.getMap(key).addAndGet(hk, number);
    }

    /**
     * 删除hash
     */
    public void deleteHash(String key, String hk) {
        redissonClient.getMap(key).remove(hk);
    }


    /**
     * 将元素添加到此集合，如果已添加，则覆盖先前的分数。
     * 参数：
     * score - - 对象得分
     * value - - 对象本身
     */
    public void addZset(String key, Object value, Double score) {
        redissonClient.getScoredSortedSet(key).add(score, value);
    }

    /**
     * 分页查询zset
     *
     * @param startIndex – - 开始索引
     * @param endIndex   – - 结束索引
     */
    public Collection<ScoredEntry<Object>> getScanZset(String key, Integer startIndex, Integer endIndex) {
        return redissonClient.getScoredSortedSet(key).entryRange(startIndex, endIndex);
    }

    /**
     * 删除Zset 根据排名
     */
    public int deleteZsetObject(String key, Integer rank) {
         return redissonClient.getScoredSortedSet(key).removeRangeByRank(rank,rank);
    }

    public int getZsetCount(String key) {
        return redissonClient.getScoredSortedSet(key).size();
    }

    public RLock getLock(String key){
        return redissonClient.getLock(key);
    }
}
